OSI 7계층
국제표준화 기구(ISO)에서 개발한 모델로서 네트워크 프로토콜 통신을 계층으로 나눔으로서 표준화와 모듈화를 통해 프로그래머가 하위 수준의 단계에 크게 신경 쓰지 않고 개발을 할 수 있으며, 계층별 독립성과 단계적 계층 때문에 오류 처리가 수월하다는 장점이 있습니다. 1층은 물리계층, 2층은 데이터링크 계층, 3층은 네트워크 계층, 4층은 전송 계층, 5층은 세션 계층, 6층은 표현 계층, 7층은 응용계층이로 나누어져 있다.
물리계층
통신케이블을 통해 데이터를 전송하는 계층입니다. 통신 단위는 bit 이며 데이터를 전송하기만 할뿐 무슨 데이터인지는 신경을 쓰지 않습니다.
데이터링크계층
송수신하는 정보가 안전하게 전달하도록 서비스하는 계층입니다. 이 계층에서는 MAC address 를 가지고 통신을 하며 전송 단위가 프레임이며 오류 검출과 흐름 제어를 통해 안전하게 도달하도록 합니다.
네트워크 계층
시스템간 연결성과 경로 선택을 제공하는 역할을 하는 계층입니다. IP address 를 이용하여 라우팅 프로토콜이 연결된 네트워크를 통한 최적경로를 선택합니다.
전송 계층
데이터의 전송을 위한 논리적인 연결을 하는 대문같은 역할을 합니다. 신뢰성 있는 전송을 보장하기 위해 오류 검출 및 복구와 흐름 제어를 제공합니다.
세션 계층
앞의 4개의 계층은 데이터 전송과 관련된 계층이라하면 앞으로의 3개 계층은 어플리케이션과 관련있는 서비스를 제공합니다. 이 계층은 어플리케이션간 세션을 구축하고 관리하며 종료하는 역할을 합니다.
표현계층이란
데이터 표현이 상이한 응용 프로세스의 독립성을 제공하고 암호화 하는 역할을 합니다. 다루고 있는 데이터가 text인지 image 인지 등을 구분합니다.
어플리케이션 계층
OSI 모델에서 가장 유저와 가까운 층으로서 상대방이 보낸 데이터의 최종 목적지가 됩니다. HTTP, FTP, SMTP 등이 이 계층에 속한 프로토콜이다.
Big endian, Little endian
엔디언이란 컴퓨터 메모리에 연속된 바이트를 배열하는 방법을 말하는데 이 순서에 있어서 최상위 바이트가 앞에 오면 빅엔디언, 최하위 바이트가 앞에 오면 리틀엔디언이라고 합니다.
Big endian. Little endian 장단점
빅엔디안의 경우 사람이 읽고 쓰는 방법과 같기에 디버깅이 쉬우나, 수가 커질 경우 메모리에 저장된 데이터를 오른쪽으로 옮겨야하는 단점이 있습니다. 반대로 리틀엔디안의 경우 디버깅은 어려울수 있으나 수가 커지더라도 오버헤드가 발생하지 않는다는 장점이 있습니다.
3-way handshaking
클라이언트와 서버가 통신을 하기전 정확한 전송을 보장하기 위해 컴퓨터간 세션을 수립하는 과정으로서 TCP 프로토콜에서 신뢰성을 보장하기 위해 사용됩니다.
3-way handshaking이 어떻게 신뢰성을 제공하는가
Handshaking 과정 설명
3-wau handshaking 과정
초기 클라이언트 상태는 CLOSED 상태이고 서버의 열려있는 포트의 상태는 LISTEN 상태입니다. 먼저 클라이언트가 서버에게 SYN 신호를 보내면 서버에서는 SYN_RCV 상태로 변경됩니다. 다시 서버는 클라이언트에게 SYN 에 대한 응답으로 ACK 를 보내는데 이때 클라이언트의 포트도 열어달라는 요청으로 SYN 를 같이 보냅니다. ACK 와 SYN 를 받은 클라이언트는 ESTABLISHED 로 변경되고 응답신호로서 ACK 를 서버에게 보낸다. 마지막으로 서버가 ACK 신호를 받으면 ESTABLISHED 상태가 되면서 클라이언트와 서버간 연결이 성공합니다.
4-way handshaking
클라이언트와 서버가 연결하기 위해 3-way handshaking 과정이 필요하듯이 연결을 종료할때에도 데이터 손실없는 전송을 보장하기 위해 handshaking 과정이 필요한데 이것이 4-way handshaking 입니다.
4-way handshaking 과정
클라이언트가 종료하겠다는 신호인 FIN 을 서버에 보내고 자신은 FIN_WAIT_1 상태로 변경됩니다. FIN 을 받은 서버는 ClOSE_WAIT 상태로 변경되고 응답으로 ACK 를 보냅니다. ACK 를 받은 클라언트는 다시 FIN_WAIT_2 상태로 변경됩니다. 이때 서버는 남은 데이터를 모두 전송하고 전송을 다하면 연결을 종료한다는 신호로 FIN 을 클라이언트에 보며 LAST_ACK 상태로 변경됩니다. FIN 을 받은 클라이언트는 TIME_WAIT 상태로 변경되면서 응답으로 ACK 를 서버에 보내고, 자신은 일정시간이 지난 후 CLOSED 상태로 변경됩니다. 마지막으로 응답신호를 받은 서버는 CLOSED 상태로 변경되면서 포트를 닫게 됩니다.
서버가 마지막에 FIN 을 보내는 이유
서버가 아직 클라이언트에 보낼 데이터가 남아있을 경우 데이터를 다 전송하지도 못한채 클라이언트에서 포트를 닫아버리게 되므로 서버 또한 종료될 준비가 되었다는 의미로 FIN 을 보내게 됩니다.
클라이언트가 마지막에 ACK 를 굳이 보내는 이유
서버가 보낸 FIN 신호를 클라언트가 받지 못 할 경우 클라이언트는 FIN_WAIT_2 상태로 종료가 되지 못한채 계속 기다리게 될 것입니다. 허나 서버는 이미 포트를 닫고 더이상 응답을 안하는 상태이기에 클라이언트는 불필요한 자원을 소모하게 됩니다.
로드밸런싱(Load balancing)
가상 ip를 통하여 하나의 서비스를 여러대의 서버가 분산 처리하는 메커니즘을 말합니다. 대표적으로 하나의 서버에 발생하는 트래픽이 많을 경우 서버의 부하량과 속도저하를 해소하거나 하나의 서버에서 장애가 발생하더라도 서비스가 중단되지 않고 지속하기 위해 사용됩니다.
분산처리를 어떻게 하는가
먼저 서버의 대표 ip를 virtual ip로 설정합니다. virtual ip로 통해 들어오는 패킷들을 L4 또는 L7 스위치를 통해 분석합니다. L4 스위치의 경우 포트를 분석하여 알맞는 서버를 찾아 보내고, L7 스위치의 경우 포트 뿐만 아니라 이메일 또는 파일 제목, url까지 분석하여 패킷을 분산처리합니다. 이때 각각의 서버에 트래픽을 균등하게 보내기 위해 Round Robin, Least Connection, Response Time, Hash 등의 기법으로 분산시킵니다.
Round Robin
각 서버에 session을 순차적으로 맺어주는 방식입니다. 모든 클라이언트를 동일하게 취급하고, 각 서버별 처리량을 기억하고 있어야 합니다.
Least Connextion
클라이언트와 서버별 연결된 connection 수를 고려하여 가장 적은 서버에 connection 을 맺는 방식입니다.
Weighted Least Connections
Least Connection 방식에서 서버에 가중치를 추가한 것으로 open 된 connection 수가 같을 경우 가중치가 높은 서버에게 우선 분배하는 방식입니다.
Response Time
서버의 응답시간에 대한 학습을 통하여 응답시간이 빠른 서버에 conneciton을 우선 분배하고 응답이 느린 서버에는 connection을 적게 분배하는 방식입니다.
Hash
Hash 알고리즘을 적용하여 특정 서버에 connection을 연결한 클라이언트는 다음 연결에도 같은 서버에 connection을 맺는 방식입니다. 한번 성립된 session을 유지할 수 있는 장점이 있습니다.
도메인(domain)
컴퓨터간 통신을 하기위해 고유숫자인 ip 를 통해 통신을 하게 되는데 숫자로만 이루어진 ip 는 사람들이 이해하거나 외우기가 어렵기에 편하게 쓰기위해 ip 별로 고유이름을 부여한 것이 도메인입니다.
IP Address와 MAC Address
IP address 는 인터넷 네트워크 상의 고유 주소이고 라우팅시에 필요합니다. MAC address 는 장치의 고유 번호로서 통신시 상대방 컴퓨터를 찾아내기 위해 필요한 주소입니다. 따라서 인터넷에 접속하여 네트워크 통신을 할때 상대방이 접속한 인터넷 망까지 IP address 를 통해 찾아가고, MAC address 를 통해 망에 접속된 장치 중 알맞는 장치에 도착할 수 있습니다.
ARP (Address Resolution Protocol) 와 RARP에 대해 설명
ARP 는 OSI 7계층의 네트워크 계층에서 사용되는 주소 결정 프로토콜로서 IP 주소에서 MAC 주소를 알아내기 위한 프로토콜이고, RARP 은 반대로 MAC 주소에서 IP 주소를 알아내기 위한 프로토콜입니다. 상대방 MAC 주소를 모를 경우 IP와 브로드 캐스팅 네트워크 주소 FFFFFFFFFFFF를 가지는 ARP 패킷을 네트워크 상에 전송하여 이를 수신한 호스트가 자신의 MAC 주소를 반송하는 메커니즘입니다. 이때 ARP 캐시라 불리는 메모리에 테이블 형태로 저장하여, 패킷을 전송할 때에 다시 사용됩니다.
리피터, 허브, 브릿지, 라우터와 L2, L3, L4, L7 스위치 차이점
리피터
리피터는 물리계층에서 단순히 전기적인 신호만 증폭시키는 장치입니다. 네트워크 신호가 연결된 모든 PC에 전달되기 때문에 연결된 장치가 많을수록 부하가 심해집니다.
허브
허브는 리피터처럼 물리계층에서 전기적인 신호를 증폭시켜 전송거리를 연장시켜주는 장치입니다. 플러딩으로 인해 네트워크 장치가 많을수록 부하가 심해지고, 잡음 신호고 증폭된다는 단점이 있습니다.
플러딩
네트워크 장치에서 신호를 보내면 연결되어 있는 모든 장치들에서 신호를 전송하는 방식을 말합니다. 따라서 보안성이 약하고, 네트워크 충돌 문제가 발생할 수 있습니다.
허브와 리피터의 차이
허브는 리피터에 몇가지 기능이 추가된 것으로 패킷 모니터링과 멀티 포트를 지원하여 문제가 생긴곳을 고립시킬 수 있습니다.
브릿지
브릿지는 데이터링크계층에서 전송거리를 연장시켜주는 장치입니다. 단순 전기적 신호를 증폭시키는 것이 아닌 프레임을 다시 만들어 전송합니다.
스위치
스위치는 브릿지와 마찬가지로 데이터링크계층에서 전송거리를 연장시켜주는 장치입니다. 스위치는 성능에 따라 L2와 L3 L4 L7스위치로 구분되는데 단순히 MAC 주소만 참조하여 처리하는 장치를 L2 스위치라고 합니다. MAC 주소와 포트번호가 기록된 MAC 주소 테이블을 가지고 있어, 목적지 MAC 주소를 가진 장비가 연결된 포트로만 프레임을 전송하기 때문에 충돌이 일어나지 않지만 MAC 주소가 브로드캐스트일 때 모든장비로 프레임을 전송하기에 성능저하가 일어납니다.
브릿지와 스위치의 차이
데이터링크 계층에서 프레임을 전송하는 역할은 같으나, 브릿지에 비해 속도와 기능이 업그레드 된 것이 스위치입니다. 따라서 대부분 스위치를 사용하고 있습니다.
스위치가 속도가 더 빠른 이유
데이터 처리 방식에 있어서 브릿지는 소프트웨어적으로만 처리하는 반면 스위치는 하드웨어적으로 처리가 가능하여 속도가 월등히 빠릅니다.
L3 스위치
L2 스위치에서 접속된 장비가 많을수록 브로드캐스트 트래픽이 증가하는 문제를 해결하기 위해 VALN이 도입되었고, 이 기술을 적용한 장치가 L3 스위치입니다. VLAN이 다르면 브로드캐스트 프레임이 차단하여 성능저하를 해결할 수 있습니다. 네트워크 계층에서 사용되는 장치입니다.
L4, L7 차이점
L4 스위치는 전송계층에서 작동하는 스위치로서 ip 주소를 통해 호스트종단으로 전송하는 것 뿐만 아니라 포트번호에 맞는 서버로 패킷을 전송하여 분산처리가 가능하다는 장점이 있습니다. L7 스위치는 응용계층에서 작동하는 스위치로서 L4 스위치보다 한단계 더 높이 패킷의 url, 쿠키, payload 일부분을 읽어서 더욱 세밀한 분산 처리를 도울 수 있는 장점이 있습니다.
라우터란
라우터는 네트워크 계층에서 IP주소를 이용해 목적지 포트로 패킷을 전송하는 장치입니다. 특히 서브넷이 다른 IP주소를 가진 장비간 통신은 이 네트워크 계층 장비를 거쳐야 합니다.
게이트웨이(Gateway)란?
외부로 연결되는 통로를 의미하며, 로컬망 라우터와 외부 망 라우터간의 통로를 말합니다.
프로토콜(Protocol)
컴퓨터간 데이터 통신을 원활하게 하기 위해 규정한 규약으로 신호 송신의 순서(handshaking)나 데이표 표현법, 요류 검출법 등을 정한 것을 말한다.
HTTP 프로토콜
한 문서에서 다른 문서로 즉시 접근할 수 있는 텍스트를 하이퍼텍스트라고 하는데 이 텍스트를 전송하는 규약을 말한다.
HTTP 1.1 에서 추가된 기능
1.0에서의 모호함과 성능을 개선하기 위해 1.1이 나왔습니다. 1.0의 경우 구조는 단순하지만 연결의 설정과 해체 반복으로 인해 네트워크 혼잡에 대한 정보를 확보할 수가 없었고, 대역폭이 낮은 링크에서는 성능저하를 발생시킵니다. 또한 캐시 모델이 미흡하여 동작상의 오버헤드와 캐시 데이터 관리에 문제가 많았습니다. 대표적으로 keepalive를 추가하여 연결의 설정과 해제의 반복을 줄이고, 캐시 제어 메커니즘이 도입되었으며, 파이프라이닝을 추가하여 동시에 여러 클라이언트와 연결을 할 수 있었으며, 요청메소드가 확장되어 PUT, DELETE 등이 추가되었습니다.
HTTP 2.0 에서 추가된 기능
1.1보다 웹 속도를 개선하기 위해 2.0이 등장하였습니다. 추가된 기능으로 SSL 환경에서만 사용가능하기 때문에 보안성이 높으며 Header의 압축을 통한 성능향상이 되었고, Server Push를 통해 클라이언트의 요청없이도 필요 데이터를 보낼 수 있게 되었습니다. 또한 하나의 TCP 커넥션 내에서 병렬 처리를 지원하여 동시 처리가 가능하게 되었습니다. 메세지 전송 포맷도 바뀌었습니다. 1.1에서는 플레인텍스트로 형태로 header와 body를 보냈다면 2.0에서는 바이너리로 인코딩하여 header와 body를 전송합니다. 바이너리로 인코딩된 데이터를 프레임 단위로 전송하며 프레임이 모여 하나의 메세지를 보냅니다. 여러 메세지는 스트림 구조로 전송되기에 다수의 메세지를 동시에 처리함으로써 빠른 응답속도를 보장하게 되었습니다.
참고
Keepalive
두 호스트간 통신이 일정시간 패킷교환이 없을 때 자동으로 연결이 해제되는데 이것을 막기 위해 주기적으로 패킷을 보내는 것을 말합니다. keepalive는 tcp와 http 프로토콜 모두에서 일어날 수 있습니다.
TCP에서 Keepalive
일정 시간동안 서로의 패킷 교환이 없을 경우 두 지점간 상대방의 안부를 묻기위해 payload 가 없는 패킷을 주기적으로 보내는 것입니다. 종단 시스템 중의 하나가 다운될 때 다른쪽 시스템만 열린 연결 상태를 정리하기 위해 사용됩니다.
HTTP에서의 Keepalive
http 는 비연결형 통신이기에 커넥션을 유지하지 않습니다. 따라서 재요청시 커넥션을 다시 설정해야되는 비용이 큽니다. 이것을 해결하기 위해 Keepalive timeout내에 재요청을하면 열려있는 커넥션을 통해 전송하는 구조가 Keepalive입니다. Keepalive Timeout 을 너무 오래 설정하면 다른 사용자가 연결을 못하게 됨으로 사용자가 많은 서버보다는 소수의 사람이 빠르게 인터넷을 사용하자 하는 환경에서 사용하는 것이 좋습니다.
POST 방식과 GET 방식
HTTP 프로토콜을 이용하여 서버에 요청방법 중 하나로서 요청방법에 따라 GET과 POST로 나뉩니다. 이때 필요에 따라 데이터를 보낼수 있는데 이때 데이터는 url 뒤에 쿼리스트링으로 입력하여 보내기에 외부에 쉽게 노출된다는 단점이 있습니다.
GET method
GET 방식은 서버에 데이터를 요청하는 방식으로서 특정 웹페이지 등을 요청할 때 쓰입니다.
POST medthod
POST 방식은 서버에 데이터를 전송을 요청하는 방식으로서 웹 페이지의 폼에 입력한 데이터를 서버에 보낼 때 쓰입니다. 데이터는 HTTP의 body에 담아 보이기에 GET처럼 대놓고 보이지 않아 안정적이라 말할 수 있으나, 암호화 되어 있지 않아 쉽게 발견될 수 있습니다.
Restfult API에서의 URL과 일반적인 HTTP 에서의 URL의 차이
일반적인 HTTP의 URL은 기능에 중점을 두어 설계를하기 때문에 회원정보를 가져온다면 ‘/getUser’ 와 같이 설계를 하지만 Restful API에서는 자원에 중점을 두고 설계를 합니다. 따라서 ‘/user’로 설계를 하되 기능에 대한 구분은 POST, GET, DELETE, PUT 등의 HTTP 메서드를 통하여 설계하는 차이가 있습니다.
Restful API
ROA(Resource Oriented Architecture) 구조를 지향하여 이미지, 텍스트, DB 등 모든 자원에 대하여 고유한 URL을 부여하도록 설계하는 방식을 말합니다.
Get 방식(그 어떤 방식이든간에)의 URL을 통해서 데이터를 전달시 보안성 취약 해결방법
SSL을 이용한 HTTPS 프로토콜로 데이터 전송을 암호화하여 보냅니다. 그러면 URL 뒤에 붙는 쿼리스트링 내용 모두 암호화되어 전송되기 때문에 보안성을 강화할 수 있습니다.
HTTPS
표현계층의 SSL 프로토콜 위에서 응용계층의 HTTP 프로토콜이 실행되는 것을 말하며, HTTP Over SSL 이란 의미입니다.
HTTPS 동작 방식
응용계층에서 HTTP 프로토콜에 따라 메세지에 데이터를 담아 표현계층으로 보냅니다. 표현계층의 SSL에 따라 메세지를 클라이언트와 주고받은 대칭키로 암호화하여 전송 계층에 보냅니다. 전송계층에서는 TCP 프로토콜에 따라 세그먼트에 메세지을 담아 클라이언트에게 보냅니다. 클라이언트는 서버에서 가공한 과정의 역순으로 진행되며 표현계층에서는 서버와 주고받은 대칭키로 복화를 하여 데이터를 열어볼 수 있게 됩니다.
SSL에 대해 설명해보아라.
OSI 7계층에서 표현계층에 속하는 보안 프로토콜로서 스니핑과 같은 악의적인 행위를 방지하기위해 만들어진 프로그램 계층이다. SSL은 디지털 증명의 사용에도 포함되는 RSA의 비대칭키 암호화 시스템을 사용한다.
(HTTPS와 SSL를 같은 의미로 이해하고 있는 경우가 많다. 이것은 맞기도 틀리기도 하다. 그것은 마치 인터넷과 웹을 같은 의미로 이해하는 것과 같다. 결론적으로 말하면 웹이 인터넷 위에서 돌아가는 서비스 중의 하나인 것처럼 HTTPS도 SSL 프로토콜 위에서 돌아가는 프로토콜이다.)
SSL 디지털 인증서
SSL 인증서는 클라이언트와 서버간의 통신을 제3자가 보증해주는 전자화된 문서다. 클라이언트가 서버에 접속한 직후에 서버는 클라이언트에게 이 인증서 정보를 전달한다. 클라이언트는 이 인증서 정보가 신뢰할 수 있는 것인지를 검증 한 후에 다음 절차를 수행하게 된다.
SSL 인증서에는 서비스의 정보 (인증서를 발급한 기관), 서버 측 공개키가 포함되어 있다.
대칭키
암호를 만드는 행위인 암호화를 할 때 사용하는 일종의 비밀번호를 키(key)라고 한다. 이 키에 따라서 암호화된 결과가 달라지기 때문에 키를 모르면 암호를 푸는 행위인 복호화를 할 수 없다. 대칭키는 동일한 키로 암호화와 복호화를 같이 할 수 있는 방식의 암호화 기법을 의미한다. 대칭키 방식은 단점이 있다. 암호를 주고 받는 사람들 사이에 대칭키를 전달하는 것이 어렵다는 점이다. 대칭키가 유출되면 키를 획득한 공격자는 암호의 내용을 복호화 할 수 있기 때문에 암호가 무용지물이 되기 때문이다. 이런 배경에서 나온 암호화 방식이 공개키방식이다.
공개키
공개키 방식은 두개의 키를 갖게 되는데 A키로 암호화를 하면 B키로 복호화 할 수 있고, B키로 암호화하면 A키로 복호화 할 수 있는 방식이다. 이 방식에 착안해서 두개의 키 중 하나를 비공개키(private key, 개인키, 비밀키라고도 부른다)로하고, 나머지를 공개키(public key)로 지정한다. 비공개키는 자신만이 가지고 있고, 공개키를 타인에게 제공한다. 공개키를 제공 받은 타인은 공개키를 이용해서 정보를 암호화한다. 암호화한 정보를 비공개키를 가지고 있는 사람에게 전송한다. 비공개키의 소유자는 이 키를 이용해서 암호화된 정보를 복호화 한다. 이 과정에서 공개키가 유출된다고해도 비공개키를 모르면 정보를 복호화 할 수 없기 때문에 안전하다. 공개키로는 암호화는 할 수 있지만 복호화는 할 수 없기 때문이다.
SSL은 공개키와 대칭키의 장점을 혼합한 방법을 사용한다. (클라이언트에서 생성한 대칭키를 서버의 공개키를 이용해 암호화해 보낸다. 그 후 데이터를 주고받는(세션) 과정에서는 대칭키를 사용한다.)
SSL의 동작 방법
SSL 역시 TCP 프로토콜 기반이라서 Handshake 과정을 거친다.
- Client는 Server에게 hello 메시지를 보냅니다. Server는 Client에게 Hello 메시지로 응답을 보냅니다. 서로간의 통신을 준비하는 단계로 보면 됩니다.
- Server는 Client에게 인증서, 사용할 서버키를 교환하며, 인증요청을 보냅니다.
- Client는 Server에게 인증서, 사용할 클라이언트키를 교환하며, 인증서 확인요청을 합니다.
- Server, Client 모두 Change Cipher Spec Protocol을 교환하며 위 단계에서 교환한 서버/클라이언트 키, 인증서 등을 토대로 이후의 통신을 지속하겠다는 메시지를 교환하며 서로의 인증을 마칩니다.
SSL의 사용 예
기본적인 통신외에 무언가 덧붙여진다는 것은 정보를 보호하는데 도움이 될지언정 속도에는 도움이 되지 않는것이 사실이다. 보안을 강화하면 편의성이 떨어진다는 것은 어쩔 수 없는 것이다. 암호화를 하기 위해 크고작은 사전절차를 거쳐야하고, 데이터를 암호화, 복호화 하는 것도 컴퓨터에게는 모두 ‘일’이기 때문이다.
따라서 모든 웹페이지를 암호화해서 HTTPS로 만들면 좋겠지만 그렇게 되면 간단한 페이지를 열어보는 것도 시간이 많이 걸릴 수 있다. 이러한 속도 문제로 인해 단순한 웹 서핑때에는 HTTPS를 사용하지 않고, 로그인이나 결제와 같은 페이지에서 주로 사용한다. 참고로 일반적인 웹 페이지 HTTP는 TCP 80 포트를 사용하고, SSL이 적용된 HTTPS 페이지는 TCP 443 포트를 사용한다.
참조
TCP와 UDP
전송계층에서 사용되는 통신규약으로서 사용되는 환경에 따라 TCP와 UDP로 나뉘게 됩니다.
UDP
UDP 데이터 중심 프로토콜로서 주고받는 통신보다 데이터를 일방적으로 보내는 것을 중요시 합니다. 따라서 데이터 전송의 신뢰성이 보장되지 않지만 그만큼 가볍고 단순한 구조이고 속도가 빨라 실시간으로 통신할 수 있는 장점이 있습니다. 보통 p2p나 스트리밍, 전화 같은 경우에 사용됩니다.
TCP
이에 반해 TCP 흐름 중심 프로토콜로서 서로가 통신을 주고 받는 것을 중요시합니다. 따라서 데이터 전송의 안전을 신경쓰기 때문에 중간에 패킷이 손실되는 경우 재전송을 통해(SYN-ACK handshaking) 신뢰성을 보장할 수 있습니다. 하지만 그만큼 전송속도가 느리다는 단점이 있습니다. TCP 프로토콜은 거의 대부분의 통신에서 사용되고 있으며, 특히 파일이나 데이터 전송시에 사용됩니다.
TCP 의 신뢰성 보장이 어떻게 이루어지는가
3-way-handshaking 과 혼잡제어, 흐름제어를 통해 신뢰성을 보장합니다.
흐름 제어 (control flow)
TCP가 신뢰성 보장을 위해 사용하는 메커니즘 중 하나로서 송신측과 수신측의 속도 차이를 해결하기 위해 사용하는 메커니즘입니다. 대표적으로 Stop and Wait ARQ, Sliding Window 기법이 있습니다.
Stop and Wait ARQ
매번 패킷을 보내고 난 후 확인 응답을 받아야만 패킷을 전송하는 방식입니다.
Sliding Window
수신측에서 설정한 윈도우 크기만큼 확인 없이 세그먼트를 전송할도록 하여 데이터 흐름을 동적으로 조절하는 방식입니다.
Window
데이터를 보내기 전 3-way-handshaking 을 통해 수신측이 데이터를 받을 수 있는 버퍼양과 송신측이 데이터를 보낼 양을 맞추게 되는데 이 데이터 양을 window size라고 합니다.
Go-Back-N ARQ
누적 응답을 사용한 방식으로 응답신호가 손실되더라도 이후 순서의 응답신호를 받으면 window가 shift 됩니다. timer가 하나이기에 순서가 낮은 프레임이 손실되면 이후의 모든 프레임을 재전송합니다. 수신측의 window 사이즈가 1로 설정되어 있어 프레임을 순차적으로만 수신할 수 있습니다.
Selective Repeat ARQ
선택 응답을 사용한 방식으로 window의 가장 처음 프레임의 응답신호를 받아야 window가 shift 됩니다. 각 프레임당 timer가 동작하고 순서가 낮은 프레임이 손실되더라도 해당 프레임만 재전송합니다. 송신측과 수신측의 window size가 같기에 수신측에서 프레임 순서와 상관없이 수신이 가능합니다.
혼잡제어 (congestion control)
TCP가 신뢰성 보장을 위해 사용하는 메커니즘 중 하나로서 네트워크의 혼잡을 피하기 위해 송신자의 전송속도를 줄이기 위해 사용하는 메커니즘입니다. 대표적으로 AIMD, Slow Start, Fast Retransmit, Fast Recovery 기법이 있습니다.
AIME (Additive Increase/Multiplicative Decrease)
window size를 1부터 시작하여 하나씩 증가시킵니다. 혼잡상태가 감지되면 window size를 절반으로 감소시킵니다.
Slow Start
window size를 1부터 시작해서 매회 2배씩 증가시킵니다. 혼잡이 발생하면 window size를 1로 감소시킨 후 지수적으로 증가시킵니다. 혼잡이 발생했던 window size의 절반부터는 선형적으로 증가시켜 나갑니다.
Fast Retransmit
수신자가 프레임을 순서대로 받지 못햇을 경우 순서대로 받은 프레임 중 가장 최근의 프레임에 대한 ACK 신호를 보내게 됩니다. 이때 송신자는 3개 이상의 중복된 ACK를 받을 경우 timeout까지 기다리지 않고 바로 패킷을 재전송함으로서 시간을 절약합니다. 이런 현상이 반복되면 혼잡 상태로 인지하여 window size를 감소시킵니다.
Fast Recovery
Slow Start 처럼 window size를 증가시키다가 혼잡상태를 만나면 window size를 1이 아닌 절반으로 감소시킨 후 선형적으로 증가시키는 방법입니다.
Java에서 TCP와 UDP 소켓 생성 방법
TCP와 UDP 모두 소켓 프로그래밍이라는 관점에서 같지만, 서버와 클라이언트간 연결과정에서 차이를 보입니다. 일단 socket() 함수를 통해 socket을 생성하고 ip 와 port 를 socket에 bind 하는 작업을 거칩니다. 이후에 TCP에서 서버는 listen() 함수를 호출하여 클라이언트에서
TCP 소켓 생성방법
1. 클라이언트
- socket() 함수를 통해 socket 을 생성합니다. 반환값으로 소켓 지정 번호가 부여됩니다.
- socket(domain, type, protocol)
- domain - 소켓 사용영역 (AF_INET, AF_UNIX)
- type - 소켓 유형 (SOCKET_STREAM - IPPROTO_TCP, SOCKET_DGRAM - IPPROTO_UDP)
- protocol - 사용할 프로토콜 (IPPROTO_TCP, IPPROTO_UDP)
- socket(domain, type, protocol)
- connect() 함수를 통해 연결할 ip 와 port 번호를 지정합니다. 클라이언트에서 connect() 가 ip주소와 port번호를 binding 하는 역할을 하며 커널에 소켓을 등록함으로서 커널이 외부와 통신할 귀를 열어놓게 됩니다.
- connect(sockfd, serv_addr, addrlen
- sockfd - 소켓 지정 번호
- serv_addr - 연결할 서버에 대한 소켓 주소 구조체
- addrlen - 구조체 크기
- connect(sockfd, serv_addr, addrlen
- read(), write() 함수를 를 통해서 데이터를 주고 받습니다.
- read(fd, buf, count), write(fd, buf, count)
- fd - 소켓 지정 번호
- buf - 데이터를 담거나 담을 버퍼
- count - 버퍼의 크기
- read(fd, buf, count), write(fd, buf, count)
- 작업이 끝나면 close() 함수를 통해서 연결을 종료합니다.
- close(sockfd)
- sockfd - 소켓 지정 번호
- close(sockfd)
2. 서버
- socket() 함수를 통해 socket 을 생성합니다. 반환값으로 소켓 지정 번호가 부여됩니다.
- socket 에 지정할 ip 와 port 번호를 bind() 함수를 통해 binding 합니다.
- bind(sockfd, addr, addrlen)
- socked - 소켓 지정 번호
- addr - 소켓 주소 구조체 (소켓 유형, 연결할 대상의 ip 주소와 port 번호를 가진다.)
- addrlen - 구조체의 크기
- bind(sockfd, addr, addrlen)
- listen() 함수를 통해 수신 대기열을 설정하여 여러 클라이언트 요청 저장합니다.
- listen(queue_size)
- queue_size - 수신 대기열 크기
- listen(queue_size)
- accept() 함수를 통해 수신 대기열에 있는 요청을 가져와 연결합니다. 연결이 성공하면 새로운 소켓인 연결 소켓을 생성합니다. 연결 소켓과 듣기 소켓을 따로 구분하는 이유는 동시에 여러 클라이언트의 요청을 처리하기 위함입니다. 만약 소켓이 하나라면 하나의 클라이언트의 요청만 처리할 수 있을 것이기 때문입니다.
- accept(sockfd, addr, addrlen)
- sockfd - 듣기 소켓 지정 번호 (socket()을 통해 처음 생성했던 소켓의 지정번호)
- addr - 새로운 소켓에 바인드할 소켓 주소 구조체
- addrlen - 구조체의 크기
- accept(sockfd, addr, addrlen)
- read(), write() 함수를 통해서 데이터를 주고 받습니다.
- 작업이 끝나면 close() 함수를 통하여 연결을 종료합니다.
UDP 소켓 생성방법
1. 송신자
- socket() 함수를 통하여 연결에 사용할 소켓을 생성합니다.
- socket(AF_INET, SOCK_DGRAM, 0);
- bind() 함수를 통하여 통신할 서버의 ip 주소와 port 번호를 소켓에 binding 합니다.
- sendto(), recvfrom() 함수를 통하여 데이터를 주고 받습니다. UDP에서는 read() 나 write() 함수를 쓸 수가 없습니다. TCP처럼 연결을 맺지 않기 때문에 데이터를 읽을때마다 누가 보냈는지 확인해야하기 때문입니다.
- sendto(s, message, msglen, flags, addr, addrlen)
- s - 소켓 지정 번호
- message - 보낼 데이터
- msgflen - 데이터 크기
- flags - 전송을 위한 옵션 (대부분 0)
- addr - 소켓 주소 구조체 (소켓 유형, 연결할 대상의 ip 주소와 port 번호를 가진다.)
- addrlen - 소케 주소 구조체 크기
- recvfrom(s, buf, buflen, flags, fromaddr, fromlen)
- s - 소켓 지정 번호
- buf - 데이터를 담을 버퍼
- buflen - 버퍼의 크기
- flags - 수신을 위한 옵션
- fromaddr - 소켓 주소 구조체 (소켓 유형, 연결할 대상의 ip 주소와 port 번호를 가진다.)
- fromlen - 소켓 주소 구조체의 크기
- sendto(s, message, msglen, flags, addr, addrlen)
- 작업이 끝나면 close() 함수를 통하여 작업을 종료합니다.
2. 수신자
- socket() 함수를 통하여 연결에 사용할 소켓을 생성합니다.
- bind() 함수를 통하여 통신할 서버의 ip 주소와 port 번호를 소켓에 binding 합니다.
- sendto(), recvfrom() 함수를 통하여 데이터를 주고 받습니다.
- 작업이 끝나면 close() 함수를 통하여 작업을 종료합니다.
참조
TCP와 UDP 패킷 구조의 차이 ?
TCP 패킷구조
먼저 source / destination port number 를 가지고 있습니다. 패킷의 순서를 매기기 위한 Sequence number 와 마지막에 수신한 패킷을 알려주기 위한 Acknowledgement number 를 가지고 있습니다. 헤더크기와 잡음 및 변조를 확인하기 위한 checksum 이 있고, 데이터 관리 제어를 하는 6개의 flag 가 있습니다. 마지막으로 송수신 버퍼를 맞추기 위한 window size 를 가지고 있는 구조입니다.
UDP 패킷구조
TCP 헤더에 비해 훨씬 간단합니다. source, destination port 와 헤더 길이, 잡음과 변조를 확인하기 위한 checksum이 있습니다.
애플리케이션에서 사용하는 프로토콜의 종류 3가지
HTTP, SMTP, FTP, DHCP
브라우저에 URL을 치면 어떤 과정을 거쳐서 어떤 일이 발생하는지 네트워크 통신의 전반적인 흐름을 설명 ?
서브넷 마스크 사용하여 A, B, C, D class 쪼개는 법 ? (NHN엔터에 나온 문제)
이 포스트가 도움이 되었다고 생각하시면, 위의 버튼을 클릭하여 후원해주세요.
이 포스트를 공유하려면 QR 코드를 스캔하세요.